#include <OWidget.h>

OWidget::OWidget(OWidget *parent)
{
	pParent=parent;
	if(parent){
		parent->AddChild(this);
		dfb=parent->dfb;
	}
	dfb->GetDisplayLayer(dfb,DLID_PRIMARY,&layer);
	
	widgetdesc.flags  = (DFBWindowDescriptionFlags)(DWDESC_POSX | DWDESC_POSY |
	DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_CAPS);
	widgetdesc.posx   = 0;
	widgetdesc.posy   = 0;
	widgetdesc.width  = 1;
	widgetdesc.height = 1;
	widgetdesc.caps   = (DFBWindowCapabilities)( DWCAPS_DOUBLEBUFFER);
	layer->CreateWindow(layer, &widgetdesc, &window );
	window->SetOptions( window, (DFBWindowOptions)(DWOP_ALPHACHANNEL));
	SetStacking();
	window->GetSurface(window,&surface);
	surface->SetDrawingFlags( surface, DSDRAW_BLEND );
	surface->Clear(surface,0,0,0,0);
	SetPosition(0,0);
	SetOpacity(255);
	Show();
}

OWidget::OWidget(IDirectFB *d)
{
	DFBDisplayLayerConfig config;
	dfb=d;
	pParent=NULL;
	
	dfb->GetDisplayLayer(dfb,DLID_PRIMARY,&layer);
	layer->GetConfiguration( layer, &config );		

	widgetdesc.flags  = (DFBWindowDescriptionFlags)(DWDESC_POSX | DWDESC_POSY |
	DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_CAPS);
	widgetdesc.posx   = 0;
	widgetdesc.posy   = 0;
	widgetdesc.width  = config.width;
	widgetdesc.height = config.height;
	widgetdesc.caps   = (DFBWindowCapabilities)( DWCAPS_DOUBLEBUFFER);
	layer->CreateWindow(layer, &widgetdesc, &window );
	window->SetOptions( window, (DFBWindowOptions)(DWOP_ALPHACHANNEL));
	window->GetSurface(window,&surface);
	surface->SetDrawingFlags( surface, DSDRAW_BLEND );
	surface->Clear(surface,0,0,0,255);
	SetSize(config.width,config.height);
	SetPosition(0,0);
	SetOpacity(255);
	Show();
}

OWidget::~OWidget()
{
	int i,count;
	count=GetChildCount();
	for(i=0;i<count;i++)
		delete ChildList.at(i);
	surface->Release(surface);
}

OWidget *OWidget::GetChild(int i)
{
	if(i>GetChildCount())
		return NULL;
	return ChildList.at(i);
}

void OWidget::SetStacking()
{
	window->SetStackingClass( window, (DFBWindowStackingClass)DWSC_UPPER );
	if(pParent->GetChildCount()>1)
		PutAtop(window,pParent->GetChild(pParent->GetChildCount()-1));
	else
		PutAtop(window,pParent);
}

void OWidget::SetBackgroundColor(u8 r, u8 g, u8 b, u8 a)
{
	window->SetColor( window, r, g, b, a );
}

void OWidget::SetColor(u8 r,u8 g,u8 b,u8 a)
{
	surface->SetColor( surface, r, g, b, a );
}

void OWidget::SetPosition(u16 x, u16 y)
{
	int i,count;
	pAbsX=0;
	pAbsY=0;
	if(pParent){
		pAbsX=pParent->pAbsX;
		pAbsY=pParent->pAbsY;
	}
	pAbsX+=pX;
	pAbsY+=pY;
	window->MoveTo(window,pAbsX,pAbsY);
	count=GetChildCount();
	for(i=0;i<count;i++)
		ChildList.at(i)->SetPosition(x,y);
}

void OWidget::SetSize(u16 width, u16 height)
{
	pWidth=width;
	pHeight=height;
	window->Resize(window,pWidth,pHeight);
}

void OWidget::SetOpacity(u8 opacity)
{
	pOpacity=opacity;
	window->SetOpacity(window,pOpacity);
}

void OWidget::Update()
{
	int i,count;
	DFBRegion r;
	count=GetChildCount();
	for(i=0;i<count;i++)
		ChildList.at(i)->Update();
	r.x1=0;
	r.y1=0;
	r.x2=pWidth;
	r.y2=pHeight;
	window->BeginUpdates(window,&r);
}

void OWidget::Invalid()
{
	surface->Flip( surface, NULL, DSFLIP_ONSYNC);
}

int OWidget::AddChild(OWidget *child)
{
	ChildList.push_back(child);
	child->pParent=this;
	return ChildList.size();
}

int OWidget::GetChildCount()
{
	return ChildList.size();
}

int OWidget::GetSizeHeight()
{
	return pHeight;
}

int OWidget::GetSizeWidth()
{
	return pWidth;
}

int OWidget::GetPosX()
{
	return pX;
}

int OWidget::GetPosY()
{
	return pY;
}

OWidget *OWidget::GetParent()
{
	return pParent;
}

void OWidget::Hide()
{
	window->SetOpacity( window, 0 );
	pVisiable=false;
}

void OWidget::Show()
{
	window->SetOpacity( window, pOpacity );
	pVisiable=true;
}

bool OWidget::IsVisiable()
{
	return pVisiable;
}
